import logging
import sqlalchemy.engine.row
from enumobjects.general_enum import YesOrNoEnum
from utils.common_util import CommonUtil


class AbstractBaseBLL(object):
    def __init__(self, request, cls=None, unique_fields=None):
        self.request = request
        self.cls = cls
        self.unique_fields = unique_fields
        self.db_session = self._get_db_session()

    def _get_db_session(self):
        return self.request.db_session if hasattr(self.request, "db_session") else None

    @classmethod
    def response_data(cls, page_num, page_size, data, count):
        return {
            "page_num": page_num,
            "page_size": page_size,
            "count": count,
            "data_list": data,
        }

    @classmethod
    def is_time_field(cls, field, v):
        return ("time" in str(field)
                or "date" in str(field)
                or str(field).startswith("start")
                or str(field).startswith("end")) \
            and len(str(v)) == 10

    def get_system_user_dict(self, obj_list):
        system_user_id_list = []
        for obj in obj_list:
            # 存在join类型查询时，obj可能是一个列表
            obj = obj if not isinstance(obj, sqlalchemy.engine.row.Row) else obj[0]
            if hasattr(obj, "create_user_id") and obj.create_user_id:
                system_user_id_list.append(obj.create_user_id)
            if hasattr(obj, "last_update_user_id") and obj.last_update_user_id:
                system_user_id_list.append(obj.last_update_user_id)
        system_user_id_list = set(system_user_id_list)
        from models.user_models.system_user_model import SystemUsers
        system_user_obj_list = self.request.db_session.query(SystemUsers.id, SystemUsers.name,
                                                             SystemUsers.username).filter(
            SystemUsers.id.in_(system_user_id_list),
            SystemUsers.is_delete == YesOrNoEnum.NO.value,
        ).all()
        system_user_dict = {
            item[0]: {
                "name": item[1],
                "username": item[2],
            } for item in system_user_obj_list
        }
        return system_user_dict

    def get_list_by_obj_list(self, obj_list, join_list=None, enum_list=None):

        join_field_list = [item["field"] for item in join_list] if join_list else []
        enum_field_list = [item["field"] for item in enum_list] if enum_list else []
        join_field_dict = {
            item['field']: item["query_fields"] for item in join_list
        } if join_list else {}
        enum_field_dict = {
            item['field']: item["enum_cls"] for item in enum_list
        } if enum_list else {}

        if not hasattr(self.cls, "no_display_field"):
            no_display_field = ["id", "is_delete"]
        else:

            no_display_field = set(["is_delete"] + self.cls().no_display_field)
        res, all_field = [], []

        table_columns = self.cls.__table__.columns
        system_user_dict = self.get_system_user_dict(obj_list)
        for all_obj in obj_list:
            data = {}
            obj = all_obj if not join_list else all_obj[0]
            for col in table_columns:
                col_name = col.name
                if col_name not in no_display_field:
                    v = getattr(obj, col_name)
                    if self.is_time_field(col_name, v):
                        data[col_name] = str(CommonUtil.convert_timestamp_to_dt(v))
                        continue

                    if col_name in ['create_user_id', 'last_update_user_id']:
                        data[col_name] = system_user_dict[v] \
                            if v in system_user_dict.keys() else None
                        continue

                    if col_name in enum_field_list:
                        v = int(v) if CommonUtil.check_is_number(v) else v
                        try:
                            data[col_name] = {
                                "value": v,
                                "text": enum_field_dict[col_name].to_frontend_desc(v)
                            }
                        except Exception as ex:
                            logging.info("枚举值缺失，字段：%s，值：%s，类：%s。%s"
                                         % (str(col_name), str(v),
                                            str(enum_field_dict[col_name]),
                                            str(ex)))
                            data[col_name] = {
                                "key": v,
                                "value": ""
                            }
                        continue

                    if col_name not in join_field_list:
                        data[col_name] = v
                    else:
                        _index = join_field_list.index(col_name)
                        _index_obj = all_obj[_index + 1]
                        data[col_name] = {
                            _join_field_item: getattr(_index_obj, _join_field_item) for _join_field_item in
                            join_field_dict[col_name]
                        } if _index_obj else None
            res.append(data)
        return res
